﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using QDJwt.Token;
using MyApp.DB;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using QDCommon.SignalR;
using log4net.Repository;
using log4net;
using log4net.Config;
using System.IO;

namespace MyApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public static ILoggerRepository repository { get; set; }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region Log
            repository = LogManager.CreateRepository("NETCoreRepository");
            //指定配置文件
            XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
            #endregion
            #region JWT
            var audienceConfig = Configuration.GetSection("Audience");
            var symmetricKeyAsBase64 = audienceConfig["Secret"];
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);

            var tokenValidationParameters = new TokenValidationParameters
            {

               // The signing key must match!
               ValidateIssuerSigningKey = true,
               IssuerSigningKey = signingKey,

               // Validate the JWT Issuer (iss) claim
               ValidateIssuer = true,
               ValidIssuer = audienceConfig["Issuer"],

               // Validate the JWT Audience (aud) claim
               ValidateAudience = true,
               ValidAudience = audienceConfig["Audience"],

               // Validate the token expiry
               ValidateLifetime = true,

               ClockSkew = TimeSpan.Zero
            };
            services.AddAuthentication(options =>
            {
               options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
               options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(o =>
            {
               //不使用https
               o.RequireHttpsMetadata = false;
               o.TokenValidationParameters = tokenValidationParameters;
            });

            TokenProviderOptions option = new TokenProviderOptions()
            {
               Audience = audienceConfig["Audience"],
               Issuer = audienceConfig["Issuer"],
               Expiration = TimeSpan.FromDays(1),
               SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature)
            };

            services.AddSingleton(new TokenGenerator(option));
            #endregion
            services.AddSingleton<MysqlManager>(new MysqlManager(Configuration["DB"]));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddJsonOptions(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //不使用驼峰样式的key
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
            });
            #region SignalR
            services.AddSignalR();
            // services.AddCors(options =>
            // {
            //     options.AddPolicy("SignalrCore",
            //         policy => policy.AllowAnyOrigin()
            //                         .AllowAnyHeader()
            //                         .AllowAnyMethod());
            // });
            #endregion
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseAuthentication();
             app.UseHttpsRedirection();
            // app.UseCors("SignalrCore");
            app.UseSignalR(routes =>
            {
               routes.MapHub<QDHub>("/qdhub");
            });
    
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
